from .data_feed import MarketData
import numpy as np
import pandas as pd
from datetime import datetime, timedelta

class DataNormalizer:
    """数据标准化处理器"""
    def __init__(self, config=None):
        self.config = config or {}
        self.normalization_params = {}
        self.timezone_offset = 0  # UTC偏移量（秒）
        
    def normalize_market_data(self, raw_data):
        """标准化市场数据"""
        if isinstance(raw_data, MarketData):
            # 已经是标准格式，直接返回
            return raw_data
        
        # 根据不同数据源格式进行标准化
        data_type = self._detect_data_type(raw_data)
        
        if data_type == 'dict':
            return self._normalize_dict_data(raw_data)
        elif data_type == 'pandas':
            return self._normalize_pandas_data(raw_data)
        elif data_type == 'custom':
            return self._normalize_custom_format(raw_data)
        else:
            raise ValueError(f"Unsupported data type: {type(raw_data)}")
    
    def _detect_data_type(self, raw_data):
        """检测数据类型"""
        if isinstance(raw_data, dict):
            return 'dict'
        elif isinstance(raw_data, (pd.DataFrame, pd.Series)):
            return 'pandas'
        elif hasattr(raw_data, 'to_dict'):
            return 'custom'
        return 'unknown'
    
    def _normalize_dict_data(self, raw_data):
        """标准化字典格式数据"""
        # 提取必要字段，适配不同数据源的字段名称
        symbol = raw_data.get('symbol') or raw_data.get('code') or raw_data.get('ticker')
        price = raw_data.get('price') or raw_data.get('last') or raw_data.get('close')
        volume = raw_data.get('volume') or raw_data.get('vol') or 0
        
        # 处理时间戳
        timestamp = raw_data.get('timestamp')
        if isinstance(timestamp, str):
            try:
                # 尝试解析各种时间格式
                if len(timestamp) == 10:  # 假设是10位时间戳
                    timestamp = int(timestamp)
                elif len(timestamp) > 10:  # 假设是字符串格式
                    dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
                    timestamp = int(dt.timestamp() * 1000)  # 转换为毫秒
            except:
                timestamp = int(datetime.now().timestamp() * 1000)
        elif not timestamp:
            timestamp = int(datetime.now().timestamp() * 1000)
        
        # 提取交易所和数据类型
        exchange = raw_data.get('exchange') or raw_data.get('market') or 'unknown'
        data_type = raw_data.get('data_type') or 'tick'
        
        # 收集其他字段作为additional_fields
        additional_fields = {}
        for key, value in raw_data.items():
            if key not in ['symbol', 'price', 'volume', 'timestamp', 'exchange', 'data_type']:
                additional_fields[key] = value
        
        return MarketData(
            symbol=symbol,
            price=price,
            volume=volume,
            timestamp=timestamp,
            exchange=exchange,
            data_type=data_type,
            additional_fields=additional_fields
        )
    
    def _normalize_pandas_data(self, raw_data):
        """标准化pandas格式数据"""
        # 这里处理批量数据标准化，返回MarketData对象列表
        normalized_data = []
        
        if isinstance(raw_data, pd.Series):
            raw_data = pd.DataFrame([raw_data])
        
        for _, row in raw_data.iterrows():
            # 将行数据转换为字典并标准化
            data_dict = row.to_dict()
            normalized_data.append(self._normalize_dict_data(data_dict))
        
        return normalized_data
    
    def _normalize_custom_format(self, raw_data):
        """标准化自定义格式数据"""
        # 尝试调用对象的to_dict方法进行转换
        try:
            data_dict = raw_data.to_dict()
            return self._normalize_dict_data(data_dict)
        except Exception as e:
            raise ValueError(f"Failed to normalize custom data format: {str(e)}")
    
    def set_timezone_offset(self, offset_seconds):
        """设置时区偏移量"""
        self.timezone_offset = offset_seconds
    
    def batch_normalize(self, data_list):
        """批量标准化数据"""
        return [self.normalize_market_data(data) for data in data_list]
    
    def normalize_price(self, price, symbol=None):
        """价格标准化（去除异常值）"""
        if not isinstance(price, (int, float)) or np.isnan(price):
            return 0.0
        
        # 获取该标的的价格范围参数
        if symbol and symbol in self.normalization_params:
            params = self.normalization_params[symbol]
            min_price = params.get('min_price', 0.001)
            max_price = params.get('max_price', 100000.0)
            
            # 限制价格在合理范围内
            if price < min_price:
                price = min_price
            elif price > max_price:
                price = max_price
        
        return price
    
    def update_normalization_params(self, symbol, params):
        """更新标准化参数"""
        self.normalization_params[symbol] = params